using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
using System;
using System.Collections.Generic;

namespace Microsoft.SqlServer.Management.SqlManagerUI.Scripting
{
using Server = Microsoft.SqlServer.Management.Smo.Server;
	internal class ScriptSourceFactory
	{
		public ScriptSource CreateScriptSource(Server server, Urn[] urns, DiscoveryTasks discoverDependencies, bool isDataOnly)
		{
			if (server == null)
			{
				throw new ArgumentNullException("server");
			}
			if (urns == null)
			{
				throw new ArgumentNullException("urns");
			}
			List<Urn> list = new List<Urn>(urns);
			this.AddTriggers(list, server, urns, discoverDependencies);
			IEnumerable<Urn> enumerable = this.GetCreateDependencies(server, list, isDataOnly);
			enumerable = this.IgnoreUnResolvedEntities(enumerable);
			List<Urn> list2 = new List<Urn>();
			foreach (Urn current in enumerable)
			{
				list2.Add(current);
			}
			list2.Reverse();
			if ((discoverDependencies & DiscoveryTasks.CreateDependencies) > DiscoveryTasks.None)
			{
				ScriptSourceFactory.Merge(list, enumerable);
			}
			if ((discoverDependencies & DiscoveryTasks.DropDependencies) > DiscoveryTasks.None)
			{
				ScriptSourceFactory.Merge(list, list2);
			}
			return new ScriptSource(this.FilterSystemObjectsAndUnresolvedEntities(list, server), enumerable, list2);
		}

		protected virtual TriggerDiscovery GetTriggerDiscovery()
		{
			return new TriggerDiscovery();
		}

		protected virtual DependencyDiscovery GetDependencyDiscovery()
		{
			return new DependencyDiscovery();
		}

		private List<Urn> IgnoreUnResolvedEntities(IEnumerable<Urn> dependencies)
		{
			List<Urn> list = new List<Urn>();
			foreach (Urn current in dependencies)
			{
				if (!(current.Type == "UnresolvedEntity"))
				{
					list.Add(current);
				}
			}
			return list;
		}

		protected virtual IEnumerable<Urn> GetCreateDependencies(Server server, IEnumerable<Urn> sourceUrns, bool isDataOnly)
		{
			return this.GetDependencyDiscovery().GetCreateDependencies(server, sourceUrns, isDataOnly);
		}

		protected virtual IEnumerable<Urn> FilterSystemObjectsAndUnresolvedEntities(IEnumerable<Urn> objectList, Server server)
		{
			List<Urn> list = new List<Urn>();
			foreach (Urn current in objectList)
			{
				if (!(current.Type == "UnresolvedEntity"))
				{
					SqlSmoObject smoObject = server.GetSmoObject(current);
					if (!smoObject.Properties.Contains("IsSystemObject") || !(bool)smoObject.Properties["IsSystemObject"].Value)
					{
						list.Add(current);
					}
				}
			}
			return list;
		}

		private void AddTriggers(List<Urn> objectList, Server server, Urn[] sourceUrns, DiscoveryTasks discoverDependencies)
		{
			if ((discoverDependencies & DiscoveryTasks.Triggers) == DiscoveryTasks.None)
			{
				return;
			}
			TriggerDiscovery triggerDiscovery = this.GetTriggerDiscovery();
			objectList.AddRange(triggerDiscovery.GetTriggers(server, sourceUrns));
		}

		private static void Merge(List<Urn> target, IEnumerable<Urn> source)
		{
			if (source == null)
			{
				return;
			}
			foreach (Urn current in source)
			{
				if (!target.Contains(current))
				{
					target.Add(current);
				}
			}
		}
	}
}
